package com.smarthome.web.property.auth;

import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.config.Ini;
import org.apache.shiro.config.Ini.Section;
import org.apache.shiro.web.filter.mgt.FilterChainResolver;
import org.apache.shiro.web.mgt.WebSecurityManager;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.beans.factory.FactoryBean;

import com.smarthome.core.user.UserResourceService;
import com.smarthome.domain.bean.ShUserResource;

public class FilterChainDefinitionExtend implements FactoryBean<Ini.Section> {

    private String filterChainDefinitions;

    @Resource
    private UserResourceService userResourceService;

    public void setFilterChainDefinitions(String filterChainDefinitions) {
        this.filterChainDefinitions = filterChainDefinitions;
    }

    @Override
    public Section getObject() throws Exception {
        Ini ini = new Ini();
        ini.load(filterChainDefinitions); // 先载入XML中定义好的chain
        Ini.Section section = ini.getSection(Ini.DEFAULT_SECTION_NAME);
        List<ShUserResource> shUserResources = userResourceService.queryAllOpenedUserResources();
        for (ShUserResource shUserResource : shUserResources) {
            if (!StringUtils.isBlank(shUserResource.getAddress()))
                section.put(shUserResource.getAddress(), "authc,perms[" + shUserResource.getCode() + "]");
        }
        section.put("/**", "authc");
        return section;
    }

    @Override
    public Class<?> getObjectType() {
        return SpringShiroFilter.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    private static final class SpringShiroFilter extends AbstractShiroFilter {

        protected SpringShiroFilter(WebSecurityManager webSecurityManager, FilterChainResolver resolver) {
            super();
            if (webSecurityManager == null) {
                throw new IllegalArgumentException("WebSecurityManager property cannot be null.");
            }
            setSecurityManager(webSecurityManager);
            if (resolver != null) {
                setFilterChainResolver(resolver);
            }
        }
    }
}
